//
// Created by feng on 19-3-28.
// PS: Define the receiver data structure.
//

#include "CudaReceiver.cuh"
#include <algorithm/rayTracing/qmcrt_util/check_cuda.h>
#include <algorithm/rayTracing/qmcrt_util/global_function.cuh>

using namespace solar::cuda;

// CudaReceiver::~CudaReceiver()
// {
//     if (d_image_)
//         d_image_ = nullptr;
//     if (d_total_reflect_)
//         d_total_reflect_ = nullptr;
// }

void CudaReceiver::CClear()
{
    if (d_image_)
    {
        checkCudaErrors(cudaFreeAsync(d_image_, stream_));
        d_image_ = nullptr;
    }
    if (d_total_reflect_)
    {
        checkCudaErrors(cudaFreeAsync(d_total_reflect_, stream_));
        d_total_reflect_ = nullptr;
    }
}

/**
 * Allocate the final image matrix.
 */
void CudaReceiver::Calloc_image()
{
    // printf("----------------Calloc image---------------------------\nimage size =
    // %d\n",resolution_.x * resolution_.y);
    checkCudaErrors(cudaMallocAsync((void**)&d_image_, sizeof(float) * resolution_.x * resolution_.y, stream_));
    // checkCudaErrors(cudaMalloc((void **) &d_total_reflect_, sizeof(int) * 1024 * 125*160));
    checkCudaErrors(cudaMallocAsync((void**)&d_total_reflect_, sizeof(int) * 400 * 320, stream_));
}

/**
 * Clean the final image matrix.
 */
void CudaReceiver::Cclean_image_content()
{
    int n_resolution = resolution_.x * resolution_.y;
    checkCudaErrors(cudaMemsetAsync(d_image_, 0, sizeof(float) * n_resolution, stream_));
}

/**
 * Getters and setters of attributes for receiver object.
 */
auto CudaReceiver::getType() const -> int { return type_; }

void CudaReceiver::setType(int type) { type_ = type; }

auto CudaReceiver::getNormal() const -> float3 { return normal_; }

void CudaReceiver::setNormal(float3 normal) { normal_ = normal; }

auto CudaReceiver::getPosition() const -> float3 { return pos_; }

void CudaReceiver::setPosition(float3 pos) { pos_ = pos; }

void CudaReceiver::setRadius(float radius)
{
    radius_ = radius;
    //    printf("radius  %f\n",radius_);
}

auto CudaReceiver::getTubeUnit() const -> int { return tubeUnit_; }
void CudaReceiver::setTubeUnit(int tubeUnit) { tubeUnit_ = tubeUnit; }

auto CudaReceiver::getTube() const -> int { return tube_; }
void CudaReceiver::setTube(int tube) { tube_ = tube; }

auto CudaReceiver::getPanel() const -> int { return panel_; }
void CudaReceiver::setPanel(int panel) { panel_ = panel; }
auto CudaReceiver::getSize() const -> float3 { return size_; }

void CudaReceiver::setSize(float3 size) { size_ = size; }

auto CudaReceiver::getSurfaceIndex() const -> int { return surface_index_; }

void CudaReceiver::setSurfaceIndex(int surface_index) { surface_index_ = surface_index; }

auto CudaReceiver::getPixelLength() const -> float { return pixel_length_; }
